home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Moscow ML 1.42 / src / !runtime / md5sum.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-18  |  8.0 KB  |  447 lines  |  [TEXT/R*ch]

  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include "mlvalues.h"
  5. #include "alloc.h"
  6.  
  7. #ifdef __MWERKS__
  8. #undef nil
  9. #endif
  10.  
  11. typedef unsigned int uint;
  12. typedef unsigned char byte;
  13. extern int enc64(byte*,byte*,int);
  14.  
  15. /* Modified from md5sum.c, obtained from Netlib */
  16.  
  17. /*
  18.  *  rfc1321 requires that I include this.  The code is new.  The constants
  19.  *  all come from the rfc (hence the copyright).  We trade a table for the
  20.  *  macros in rfc.  The total size is a lot less.
  21.  *  presotto@plan9.bell-labs.com  (with tweaks by ehg@netlib.bell-labs.com)
  22.  *
  23.  *    Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
  24.  *    rights reserved.
  25.  *
  26.  *    License to copy and use this software is granted provided that it
  27.  *    is identified as the "RSA Data Security, Inc. MD5 Message-Digest
  28.  *    Algorithm" in all material mentioning or referencing this software
  29.  *    or this function.
  30.  *
  31.  *    License is also granted to make and use derivative works provided
  32.  *    that such works are identified as "derived from the RSA Data
  33.  *    Security, Inc. MD5 Message-Digest Algorithm" in all material
  34.  *    mentioning or referencing the derived work.
  35.  *
  36.  *    RSA Data Security, Inc. makes no representations concerning either
  37.  *    the merchantability of this software or the suitability of this
  38.  *    software forany particular purpose. It is provided "as is"
  39.  *    without express or implied warranty of any kind.
  40.  *    These notices must be retained in any copies of any part of this
  41.  *    documentation and/or software.
  42.  */
  43.  
  44. /*
  45.  *    Rotate amounts used in the algorithm
  46.  */
  47. enum
  48. {
  49.     S11=    7,
  50.     S12=    12,
  51.     S13=    17,
  52.     S14=    22,
  53.  
  54.     S21=    5,
  55.     S22=    9,
  56.     S23=    14,
  57.     S24=    20,
  58.  
  59.     S31=    4,
  60.     S32=    11,
  61.     S33=    16,
  62.     S34=    23,
  63.  
  64.     S41=    6,
  65.     S42=    10,
  66.     S43=    15,
  67.     S44=    21
  68. };
  69.  
  70. typedef struct Table
  71. {
  72.     uint    sin;    /* integer part of 4294967296 times abs(sin(i)) */
  73.     byte    x;    /* index into data block */
  74.     byte    rot;    /* amount to rotate left by */
  75. }Table;
  76.  
  77. Table tab[] =
  78. {
  79.     /* round 1 */
  80.     { 0xd76aa478, 0, S11},    
  81.     { 0xe8c7b756, 1, S12},    
  82.     { 0x242070db, 2, S13},    
  83.     { 0xc1bdceee, 3, S14},    
  84.     { 0xf57c0faf, 4, S11},    
  85.     { 0x4787c62a, 5, S12},    
  86.     { 0xa8304613, 6, S13},    
  87.     { 0xfd469501, 7, S14},    
  88.     { 0x698098d8, 8, S11},    
  89.     { 0x8b44f7af, 9, S12},    
  90.     { 0xffff5bb1, 10, S13},    
  91.     { 0x895cd7be, 11, S14},    
  92.     { 0x6b901122, 12, S11},    
  93.     { 0xfd987193, 13, S12},    
  94.     { 0xa679438e, 14, S13},    
  95.     { 0x49b40821, 15, S14},
  96.  
  97.     /* round 2 */
  98.     { 0xf61e2562, 1, S21},    
  99.     { 0xc040b340, 6, S22},    
  100.     { 0x265e5a51, 11, S23},    
  101.     { 0xe9b6c7aa, 0, S24},    
  102.     { 0xd62f105d, 5, S21},    
  103.     {  0x2441453, 10, S22},    
  104.     { 0xd8a1e681, 15, S23},    
  105.     { 0xe7d3fbc8, 4, S24},    
  106.     { 0x21e1cde6, 9, S21},    
  107.     { 0xc33707d6, 14, S22},    
  108.     { 0xf4d50d87, 3, S23},    
  109.     { 0x455a14ed, 8, S24},    
  110.     { 0xa9e3e905, 13, S21},    
  111.     { 0xfcefa3f8, 2, S22},    
  112.     { 0x676f02d9, 7, S23},    
  113.     { 0x8d2a4c8a, 12, S24},
  114.  
  115.     /* round 3 */
  116.     { 0xfffa3942, 5, S31},    
  117.     { 0x8771f681, 8, S32},    
  118.     { 0x6d9d6122, 11, S33},    
  119.     { 0xfde5380c, 14, S34},    
  120.     { 0xa4beea44, 1, S31},    
  121.     { 0x4bdecfa9, 4, S32},    
  122.     { 0xf6bb4b60, 7, S33},    
  123.     { 0xbebfbc70, 10, S34},    
  124.     { 0x289b7ec6, 13, S31},    
  125.     { 0xeaa127fa, 0, S32},    
  126.     { 0xd4ef3085, 3, S33},    
  127.     {  0x4881d05, 6, S34},    
  128.     { 0xd9d4d039, 9, S31},    
  129.     { 0xe6db99e5, 12, S32},    
  130.     { 0x1fa27cf8, 15, S33},    
  131.     { 0xc4ac5665, 2, S34},    
  132.  
  133.     /* round 4 */
  134.     { 0xf4292244, 0, S41},    
  135.     { 0x432aff97, 7, S42},    
  136.     { 0xab9423a7, 14, S43},    
  137.     { 0xfc93a039, 5, S44},    
  138.     { 0x655b59c3, 12, S41},    
  139.     { 0x8f0ccc92, 3, S42},    
  140.     { 0xffeff47d, 10, S43},    
  141.     { 0x85845dd1, 1, S44},    
  142.     { 0x6fa87e4f, 8, S41},    
  143.     { 0xfe2ce6e0, 15, S42},    
  144.     { 0xa3014314, 6, S43},    
  145.     { 0x4e0811a1, 13, S44},    
  146.     { 0xf7537e82, 4, S41},    
  147.     { 0xbd3af235, 11, S42},    
  148.     { 0x2ad7d2bb, 2, S43},    
  149.     { 0xeb86d391, 9, S44},    
  150. };
  151.  
  152. typedef struct MD5state
  153. {
  154.     uint len;
  155.     uint state[4];
  156. }MD5state;
  157. MD5state *nil;
  158.  
  159. void encode(byte*, uint*, uint);
  160. void decode(uint*, byte*, uint);
  161. MD5state* md5(byte*, uint, byte*, MD5state*);
  162.  
  163. value md5sum(str)     /* ML */
  164.   value str;
  165. {
  166.     byte *buf;
  167.     byte digest[16], pr64[25];
  168.     int i, n, len, start;
  169.     MD5state *s;
  170.  
  171.     s = nil;
  172.     len = string_length(str);
  173.     start = 0;
  174.     buf = calloc(256,64);
  175.     for(;;){
  176.       if (len - start < 128*64)
  177.         n = len - start;
  178.       else
  179.         n = 128*64;
  180.       bcopy(&Byte(str, start), buf, n);
  181.       start += n;
  182.       if(n <= 0 || n & 0x3f)
  183.         break;
  184.       s = md5(buf, n, 0, s);
  185.     }
  186.     md5(buf, n, digest, s);
  187.     enc64(pr64,digest,sizeof(digest));
  188.     pr64[22] = '\0';  /* chop trailing == */
  189.     free(buf);
  190.     return copy_string((char *)pr64);
  191. }
  192.  
  193. /*
  194.  *  I require len to be a multiple of 64 for all but
  195.  *  the last call
  196.  */
  197. MD5state*
  198. md5(byte *p, uint len, byte *digest, MD5state *s)
  199. {
  200.     uint a, b, c, d, tmp;
  201.     uint i, done;
  202.     Table *t;
  203.     byte *end;
  204.     uint x[16];
  205.  
  206.     if(s == nil){
  207.         s = calloc(sizeof(*s),1);
  208.         if(s == nil)
  209.             return nil;
  210.  
  211.         /* seed the state, these constants would look nicer big-endian */
  212.         s->state[0] = 0x67452301;
  213.         s->state[1] = 0xefcdab89;
  214.         s->state[2] = 0x98badcfe;
  215.         s->state[3] = 0x10325476;
  216.     }
  217.     s->len += len;
  218.  
  219.     i = len & 0x3f;
  220.     if(i || len == 0){
  221.         done = 1;
  222.  
  223.         /* pad the input, assume there's room */
  224.         if(i < 56)
  225.             i = 56 - i;
  226.         else
  227.             i = 120 - i;
  228.         if(i > 0){
  229.             memset(p + len, 0, i);
  230.             p[len] = 0x80;
  231.         }
  232.         len += i;
  233.  
  234.         /* append the count */
  235.         x[0] = s->len<<3;
  236.         x[1] = s->len>>29;
  237.         encode(p+len, x, 8);
  238.     } else
  239.         done = 0;
  240.  
  241.     for(end = p+len; p < end; p += 64){
  242.         a = s->state[0];
  243.         b = s->state[1];
  244.         c = s->state[2];
  245.         d = s->state[3];
  246.  
  247.         decode(x, p, 64);
  248.     
  249.         for(i = 0; i < 64; i++){
  250.             t = tab + i;
  251.             switch(i>>4){
  252.             case 0:
  253.                 a += (b & c) | (~b & d);
  254.                 break;
  255.             case 1:
  256.                 a += (b & d) | (c & ~d);
  257.                 break;
  258.             case 2:
  259.                 a += b ^ c ^ d;
  260.                 break;
  261.             case 3:
  262.                 a += c ^ (b | ~d);
  263.                 break;
  264.             }
  265.             a += x[t->x] + t->sin;
  266.             a = (a << t->rot) | (a >> (32 - t->rot));
  267.             a += b;
  268.     
  269.             /* rotate variables */
  270.             tmp = d;
  271.             d = c;
  272.             c = b;
  273.             b = a;
  274.             a = tmp;
  275.         }
  276.  
  277.         s->state[0] += a;
  278.         s->state[1] += b;
  279.         s->state[2] += c;
  280.         s->state[3] += d;
  281.     }
  282.  
  283.     /* return result */
  284.     if(done){
  285.         encode(digest, s->state, 16);
  286.         free(s);
  287.         return nil;
  288.     }
  289.     return s;
  290. }
  291.  
  292. /*
  293.  *    encodes input (uint) into output (byte). Assumes len is
  294.  *    a multiple of 4.
  295.  */
  296. void
  297. encode(byte *output, uint *input, uint len)
  298. {
  299.     uint x;
  300.     byte *e;
  301.  
  302.     for(e = output + len; output < e;) {
  303.         x = *input++;
  304.         *output++ = x;
  305.         *output++ = x >> 8;
  306.         *output++ = x >> 16;
  307.         *output++ = x >> 24;
  308.     }
  309. }
  310.  
  311. /*
  312.  *    decodes input (byte) into output (uint). Assumes len is
  313.  *    a multiple of 4.
  314.  */
  315. void
  316. decode(uint *output, byte *input, uint len)
  317. {
  318.     byte *e;
  319.  
  320.     for(e = input+len; input < e; input += 4)
  321.         *output++ = input[0] | (input[1] << 8) |
  322.             (input[2] << 16) | (input[3] << 24);
  323. }
  324.  
  325.  
  326.  
  327.  
  328. typedef unsigned long ulong;
  329. typedef unsigned char uchar;
  330.  
  331. static uchar t64d[256];
  332. static char t64e[64];
  333.  
  334. static void
  335. init64(void)
  336. {
  337.     int c, i;
  338.  
  339.     memset(t64d, 255, 256);
  340.     memset(t64e, '=', 64);
  341.     i = 0;
  342.     for(c = 'A'; c <= 'Z'; c++){
  343.         t64e[i] = c;
  344.         t64d[c] = i++;
  345.     }
  346.     for(c = 'a'; c <= 'z'; c++){
  347.         t64e[i] = c;
  348.         t64d[c] = i++;
  349.     }
  350.     for(c = '0'; c <= '9'; c++){
  351.         t64e[i] = c;
  352.         t64d[c] = i++;
  353.     }
  354.     t64e[i] = '+';
  355.     t64d['+'] = i++;
  356.     t64e[i] = '/';
  357.     t64d['/'] = i;
  358. }
  359.  
  360. int
  361. dec64(uchar *out, char *in, int n)
  362. {
  363.     ulong b24;
  364.     uchar *start = out;
  365.     int i, c;
  366.  
  367.     if(t64e[0] == 0)
  368.         init64();
  369.  
  370.     b24 = 0;
  371.     i = 0;
  372.     while(n-- > 0){
  373.         c = t64d[*in++];
  374.         if(c == 255)
  375.             continue;
  376.         switch(i){
  377.         case 0:
  378.             b24 = c<<18;
  379.             break;
  380.         case 1:
  381.             b24 |= c<<12;
  382.             break;
  383.         case 2:
  384.             b24 |= c<<6;
  385.             break;
  386.         case 3:
  387.             b24 |= c;
  388.             *out++ = b24>>16;
  389.             *out++ = b24>>8;
  390.             *out++ = b24;
  391.             i = -1;
  392.             break;
  393.         }
  394.         i++;
  395.     }
  396.     switch(i){
  397.     case 2:
  398.         *out++ = b24>>16;
  399.         break;
  400.     case 3:
  401.         *out++ = b24>>16;
  402.         *out++ = b24>>8;
  403.         break;
  404.     }
  405.     *out = 0;
  406.     return out - start;
  407. }
  408.  
  409. int
  410. enc64(byte *out, uchar *in, int n)
  411. {
  412.     int i;
  413.     ulong b24;
  414.     byte *start = out;
  415.  
  416.     if(t64e[0] == 0)
  417.         init64();
  418.     for(i = n/3; i > 0; i--){
  419.         b24 = (*in++)<<16;
  420.         b24 |= (*in++)<<8;
  421.         b24 |= *in++;
  422.         *out++ = t64e[(b24>>18)];
  423.         *out++ = t64e[(b24>>12)&0x3f];
  424.         *out++ = t64e[(b24>>6)&0x3f];
  425.         *out++ = t64e[(b24)&0x3f];
  426.     }
  427.  
  428.     switch(n%3){
  429.     case 2:
  430.         b24 = (*in++)<<16;
  431.         b24 |= (*in)<<8;
  432.         *out++ = t64e[(b24>>18)];
  433.         *out++ = t64e[(b24>>12)&0x3f];
  434.         *out++ = t64e[(b24>>6)&0x3f];
  435.         break;
  436.     case 1:
  437.         b24 = (*in)<<16;
  438.         *out++ = t64e[(b24>>18)];
  439.         *out++ = t64e[(b24>>12)&0x3f];
  440.         *out++ = '=';
  441.         break;
  442.     }
  443.     *out++ = '=';
  444.     *out = 0;
  445.     return out - start;
  446. }
  447.